package com.yuchen.starssdk;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yuchen.starssdk.mqtt.MqttMessageReceiveCommon;
import com.yuchen.starssdk.mqtt.MqttMessageSendCommon;
import com.yuchen.starssdk.mqtt.PubTopic;
import com.yuchen.starssdk.net.GJsonParser;
import com.yuchen.starssdk.net.NetWork;
import com.yuchen.starssdk.net.NetWorkStringCallBack;
import com.yuchen.starssdk.service.MQTTService;
import com.yuchen.starssdk.utils.DateTimeUtil;
import com.yuchen.starssdk.utils.DeviceUtil;
import com.yuchen.starssdk.utils.LogUtils;
import com.yuchen.starssdk.utils.SPManager;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;


public class StarsSdkHelper {

    private final static String TAG = "StarsSdkHelper";
    private static StarsSdkHelper instence;
    private Context mContext;
    private StarsConfig mStarsConfig;
    private boolean inited;

    private StarsSdkHelper() {
    }

    public synchronized static StarsSdkHelper getInstence() {

        if (instence == null){
            instence = new StarsSdkHelper();
        }
        return instence;
    }

    public StarsConfig getmStarsConfig() {
        return mStarsConfig;
    }

    public synchronized void  init(Context context, StarsConfig config){
        if (!inited){
            SPManager.ini(context);
            mContext = context;
            mStarsConfig = config;
            EventBus.getDefault().register(this);
        }

        inited = true;
    }

    @Subscribe
    public void onMqttAction(EbMqttAction action){
        Log.d(TAG,action.toString());
        if (mqttServiceCallBack!=null){
            if (MqttAction.connected.equals(action.getStatus())){
                mqttServiceCallBack.connectSuccess();
            }else  if (MqttAction.disconnted.equals(action.getStatus())){
                mqttServiceCallBack.disconnected();
            }else if (MqttAction.connectFail.equals(action.getStatus())){
                mqttServiceCallBack.connectFail(action.getE());
            }else if (MqttAction.deliveryComplete.equals(action.getStatus())){
                mqttServiceCallBack.messageDeliveryComplete(action.getDeliveryToken());
            }else if (MqttAction.messageArrived.equals(action.getStatus())){
                if (action.getTopic().equals("/device/register/business/"+getmStarsConfig().getDeviceSn())){
                    if (getmStarsConfig().getRegisterWay().equals(StarsConfig.REGISTER_WAY.HTTP)){
                        mqttServiceCallBack.messageArrived(action.getTopic(),action.getMqttMessage());
                    }else {
                        String msgStr = new String(action.getMqttMessage().getPayload());
                        LogUtils.d(TAG,"response resgister : "+msgStr);
                        if (null !=StarsSdkHelper.this.registOnIotPlatformCallBack){
                            MqttMessageReceiveCommon receiveCommon = JSON.parseObject(msgStr, MqttMessageReceiveCommon.class);
                            GJsonParser parser = GJsonParser.parser(receiveCommon.getMsgBody());
                            if (parser.isOk()){
                                mStarsConfig.setDeviceId(parser.parseContent().getString("deviceId"));
//                                mStarsConfig.setDeviceToken(parser.parseContent().getString("deviceToken"));
//                                mStarsConfig.doSubscribeTopics();
                                boolean refreshSubscribe = MQTTService.refreshSubscribe();
                                LogUtils.d(TAG,"refreshSubscribe : "+refreshSubscribe);
                                StarsSdkHelper.this.registOnIotPlatformCallBack.onSuccess(parser.parseContent().toJSONString());
                            }else{
                                StarsSdkHelper.this.registOnIotPlatformCallBack.onError(parser.parseMessage());
                            }

                        }
                    }
                }else{
                    mqttServiceCallBack.messageArrived(action.getTopic(),action.getMqttMessage());
                }
            }
        }

    }

    public synchronized void destory(){
        EventBus.getDefault().unregister(this);
        disconnectMqtt();
        instence = null;
    }

    public void connectMqtt(){
        Intent intent = new Intent(mContext, MQTTService.class);
        intent.putExtra("action","connect");
        mContext.startService(intent);
    }

    public void disconnectMqtt(){
        Intent intent = new Intent(mContext, MQTTService.class);
        intent.putExtra("action","disconnect");
        mContext.startService(intent);
    }


//            /sys/platform/bunsmsg/report"+"/"+动态分区号
//            "/sys/platform/bunsmsg/ack"+"/"+动态分区号

//            /sys/platform/bunsmsg/ack/1
//            /sys/platform/bunsmsg/report/1


    public void publish(MqttMessageSendCommon sendCommon){
        if(null !=sendCommon){
            MQTTService.publish(sendCommon.getMsgTopic(),JSON.toJSONString(sendCommon));
        }

    }

    public static boolean isConnected() {
        return MQTTService.isConnected();
    }

//    public void publishReport(String msg){
//        MqttMessageSendCommon sendCommon = MqttMessageSendCommon.createInstance();
//        sendCommon.setMsgTopic("/sys/platform/bunsmsg/report/"+new PartitionNumUtils().getPartitionNum(mStarsConfig.getTenantId()));
//        MQTTService.publish(sendCommon.getMsgTopic(),JSON.toJSONString(sendCommon));
//    }
//
//    public void publishAck(String msg){
//        MqttMessageSendCommon sendCommon = MqttMessageSendCommon.createInstance();
//        sendCommon.setMsgTopic("/sys/platform/bunsmsg/ack/"+new PartitionNumUtils().getPartitionNum(mStarsConfig.getTenantId()));
//        MQTTService.publish(sendCommon.getMsgTopic(),JSON.toJSONString(sendCommon));
//    }


    private MqttServiceCallBack mqttServiceCallBack;

    public void setMqttServiceCallBack(com.yuchen.starssdk.MqttServiceCallBack mqttServiceCallBack) {
        this.mqttServiceCallBack = mqttServiceCallBack;
    }

    private RegistOnIotPlatformCallBack registOnIotPlatformCallBack;

    public void setRegistOnIotPlatformCallBack(RegistOnIotPlatformCallBack registOnIotPlatformCallBack) {
        this.registOnIotPlatformCallBack = registOnIotPlatformCallBack;
    }
    public void registOnIotPlatform(){
        registOnIotPlatform(null);
    }
    public void registOnIotPlatform(final RegistOnIotPlatformCallBack registOnIotPlatformCallBack){
        if (registOnIotPlatformCallBack!=null){
            this.registOnIotPlatformCallBack = registOnIotPlatformCallBack;
        }
        mStarsConfig.setRegisterWay(StarsConfig.REGISTER_WAY.HTTP);
        JSONObject params = new JSONObject();
        params.put("deviceName",mStarsConfig.getDeviceName());
        params.put("deviceAlias",mStarsConfig.getDeviceAlias());
        params.put("deviceSn", DeviceUtil.getDeviceSn());
        params.put("productId", mStarsConfig.getProductId());
        params.put("productKey", mStarsConfig.getProductKey());
        params.put("tenantId", mStarsConfig.getTenantId());
        params.put("customerId",mStarsConfig.getCustomerId());
        params.put("bunsName",mStarsConfig.getProductName());
        params.put("additionalInfo",mStarsConfig.getAdditionalInfo());
        try{
            PackageManager packageManager = mContext.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(
                    mContext.getPackageName(), 0);
            params.put("bunsRunAppVersionCode",packageInfo.versionCode);
            params.put("bunsRunAppVersionName",packageInfo.versionName);
        }catch (Exception e){
        }


        if(mStarsConfig.getSubProductCounts()!=null && mStarsConfig.getSubProductIds()!=null && mStarsConfig.getSubProductCounts().length>0 && mStarsConfig.getSubProductIds().length>0){
            if (mStarsConfig.getSubProductIds().length!=mStarsConfig.getSubProductCounts().length){
                throw new  RuntimeException("子产品参数不正确");
            }
            JSONArray array = new JSONArray();
            for (int i=0;i<mStarsConfig.getSubProductIds().length;i++){
                JSONObject ssubProduct = new JSONObject();
                ssubProduct.put("count", mStarsConfig.getSubProductCounts()[i]);
                ssubProduct.put("subProductId", mStarsConfig.getSubProductIds()[i]);
                array.add(ssubProduct);
            }
            params.put("subProduct",array);
        }
        NetWork.getInstance()
                .postString()
                .url(mStarsConfig.getRegistUrl())
                .postStringContent(params.toJSONString())
                .build()
                .execute(new NetWorkStringCallBack() {
                    @Override
                    public void onError(String msg) {
                        if (null !=StarsSdkHelper.this.registOnIotPlatformCallBack){
                            StarsSdkHelper.this.registOnIotPlatformCallBack.onError(msg);
                        }
                    }

                    @Override
                    public void onResponse(String json) {
                        if (null !=StarsSdkHelper.this.registOnIotPlatformCallBack){
                            GJsonParser parser = GJsonParser.parser(json);
                            if (parser.isOk()){
                                mStarsConfig.setDeviceId(parser.parseContent().getString("deviceId"));
//                                mStarsConfig.setDeviceToken(parser.parseContent().getString("deviceToken"));
//                                mStarsConfig.doSubscribeTopics();
//                                StarsSdkHelper.this.registOnIotPlatformCallBack.onSuccess(parser.parseContent().toJSONString());
                                if (getmStarsConfig().getDeviceType().equals(StarsConfig.DeviceType.Direct)){
                                    StarsSdkHelper.this.registOnIotPlatformCallBack.onSuccess(parser.parseContent().toJSONString());
                                }else{
                                    getDeviceDetail();
                                }
                            }else{
                                StarsSdkHelper.this.registOnIotPlatformCallBack.onError(parser.parseMessage());
                            }

                        }
                    }
                });

    }

    private void getDeviceDetail(){
        NetWork.getInstance()
                .get()
                .url(mStarsConfig.getDetailUrl())
                .addParam("deviceId",getmStarsConfig().getDeviceId())
                .addParam("isGroup",mStarsConfig.isGroup())
                .build()
                .execute(new NetWorkStringCallBack() {
                    @Override
                    public void onError(String msg) {
                        if (null !=StarsSdkHelper.this.registOnIotPlatformCallBack){
                            StarsSdkHelper.this.registOnIotPlatformCallBack.onError(msg);
                        }
                    }

                    @Override
                    public void onResponse(String json) {
                        Log.d(TAG,json);
                        if (null !=registOnIotPlatformCallBack){
                            GJsonParser parser = GJsonParser.parser(json);
                            if (parser.isOk()){
                                JSONObject content = parser.parseContent();
                                getmStarsConfig().setDeviceInfoJson(content.toJSONString());
                                StarsSdkHelper.this.registOnIotPlatformCallBack.onSuccess(parser.parseContent().toJSONString());
                            }else{
                                StarsSdkHelper.this.registOnIotPlatformCallBack.onError(parser.parseMessage());
                            }

                        }
                    }
                });
    }

    public void registOnIotPlatformMqtt(){
        registOnIotPlatformMqtt(null);
    }

    public void registOnIotPlatformMqtt(RegistOnIotPlatformCallBack callBack){
        if (callBack!=null){
            this.registOnIotPlatformCallBack = callBack;
        }
        mStarsConfig.setRegisterWay(StarsConfig.REGISTER_WAY.MQTT);
        JSONObject params = new JSONObject();
        params.put("deviceName",mStarsConfig.getDeviceName());
        params.put("deviceAlias",mStarsConfig.getDeviceAlias());
        params.put("deviceSn", DeviceUtil.getDeviceSn());
        params.put("productId", mStarsConfig.getProductId());
        params.put("productKey", mStarsConfig.getProductKey());
        params.put("tenantId", mStarsConfig.getTenantId());
        params.put("customerId",mStarsConfig.getCustomerId());
        params.put("bunsName",mStarsConfig.getProductName());
        params.put("additionalInfo",mStarsConfig.getAdditionalInfo());
        try{
            PackageManager packageManager = mContext.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(
                    mContext.getPackageName(), 0);
            params.put("bunsRunAppVersionCode",packageInfo.versionCode);
            params.put("bunsRunAppVersionName",packageInfo.versionName);
        }catch (Exception e){
        }


        if(mStarsConfig.getSubProductCounts()!=null && mStarsConfig.getSubProductIds()!=null && mStarsConfig.getSubProductCounts().length>0 && mStarsConfig.getSubProductIds().length>0){
            if (mStarsConfig.getSubProductIds().length!=mStarsConfig.getSubProductCounts().length){
                throw new  RuntimeException("子产品参数不正确");
            }
            JSONArray array = new JSONArray();
            for (int i=0;i<mStarsConfig.getSubProductIds().length;i++){
                JSONObject ssubProduct = new JSONObject();
                ssubProduct.put("count", mStarsConfig.getSubProductCounts()[i]);
                ssubProduct.put("subProductId", mStarsConfig.getSubProductIds()[i]);
                array.add(ssubProduct);
            }
            params.put("subProduct",array);
        }
        if (!isConnected()){
            StarsSdkHelper.this.registOnIotPlatformCallBack.onError("please connect mqtt first!");
        }
        String msgId = StarsSdkHelper.getInstence().getmStarsConfig().getDeviceSn()+"_"+ DateTimeUtil.formatDateTime(System.currentTimeMillis());
        MqttMessageSendCommon sendCommon = MqttMessageSendCommon.createInstance(msgId);
        sendCommon.setMsgTopic(PubTopic.getBussRegister());
        sendCommon.setMsgBody(params.toJSONString());
        if (getmStarsConfig().getDeviceType().equals(StarsConfig.DeviceType.Direct)){
            //直链设备
            sendCommon.setMsgKey("directDevRegister");
        }else {
            //网关设备
            sendCommon.setMsgKey("gatewayDevRegister");
        }
        publish(sendCommon);
    }


    public void getDeviceDetail(final DeviceInfoOnIotPlatformCallBack infoOnIotPlatformCallBack){
        NetWork.getInstance()
                .get()
                .url(mStarsConfig.getDetailUrl())
                .addParam("deviceId",getmStarsConfig().getDeviceId())
                .build()
                .execute(new NetWorkStringCallBack() {
                    @Override
                    public void onError(String msg) {
                        LogUtils.e(TAG,msg);
                        if (null !=infoOnIotPlatformCallBack){
                            infoOnIotPlatformCallBack.onError(msg);
                        }
                    }

                    @Override
                    public void onResponse(String json) {
                        LogUtils.d(TAG,json);
                        if (null !=infoOnIotPlatformCallBack){
                            GJsonParser parser = GJsonParser.parser(json);
                            if (parser.isOk()){
                                getmStarsConfig().setDeviceInfoJson(parser.jo.getString("content"));
                                infoOnIotPlatformCallBack.onSuccess(parser.parseContent().toJSONString());
                            }else{
                                infoOnIotPlatformCallBack.onError(parser.parseMessage());
                            }

                        }
                    }
                });
    }




}
